﻿--lua script
--处理盗梦空间相关的操作

--#include "data\config\dmkj\Dmkj.lua" once
--#include "data\config\ActorEvent\TreasureIntegralCfg.lua" once
--#include "data\functions\Activity\Common\Awards.lua" once
--#include "data\functions\Activity\DailyActivity\NationwideRedPackets.lua" once    --全民红包
--#include "data\functions\Activity\Operation\operation.lua" once	--运营活动

DmkjOpId = {
	enInfo = 1,			--个人寻宝库信息
	enDm = 2,			--盗梦
	enIndex = 3,		--首页信息
	enExChangeItem = 4,	--宝藏积分兑换物品
	enAward = 5,		--领取个人寻宝
	enRefresh = 6,		--刷新个人寻宝库
}

DmkjOpFuncList = {}

EventCallDispatcher.HandlerDmkjOp = function (sysarg, args)
	if args[1] == nil then return end   --
	local func = DmkjOpFuncList[args[1]]
	if func ~= nil then
		func(sysarg, args)
	end
end


-- 寻宝物品列表索引,当前只有1个,可以扩展更多库
function GetDmkjRandTableIndex()
	local nCombineDays = System.getDaysSinceCombineServer() -- 合服天数
	local nWorldCircle = System.getCultureCircle() --全服转数
	if nCombineDays >= 1 and nCombineDays <= 3 then
		if nWorldCircle <= 4 then
			return 10
		elseif nWorldCircle <= 6 then
			return 11
		elseif nWorldCircle <= 8 then
			return 12
		elseif nWorldCircle <= 10 then
			return 13
		elseif nWorldCircle <= 12 then
			return 14
		elseif nWorldCircle <= 14 then
			return 15
		elseif nWorldCircle <= 16 then
			return 16
		else 
			return 17
		end
	else
		if nWorldCircle <= 2 then
			return 1
		elseif nWorldCircle <= 4 then
			return 2
		elseif nWorldCircle <= 6 then
			return 3
		elseif nWorldCircle <= 8 then
			return 4
		elseif nWorldCircle <= 10 then
			return 5
		elseif nWorldCircle <= 12 then
			return 6
		elseif nWorldCircle <= 14 then
			return 7
		elseif nWorldCircle <= 16 then
			return 8
		else 
			return 9
		end
	end
end

function StartXB(sysarg, consumeType)
	local var = Actor.getStaticVar(sysarg)
	if not var.days then var.days = {} end
		
	local id = DmkjConf.nomItemId	-- 默认道具
	local Prompt = 0				-- 默认不广播
	local num = 1					-- 默认数量	
	local bind = 1					-- 默认绑定
	local initSmithId = 0			-- 极品属性库
	local initSmithAttr = 0			-- 极品属性
	local equipStar		= 0			-- 强化星级
	
	local dmkjCount = var.dmkjCount or 0
	if dmkjCount >= DmkjConf.TimesRange[1] then
		if dmkjCount >= DmkjConf.TimesRange[2] then
			consumeType = 3			-- 珍品
		else
			local v = DmkjConf.TimesRange[2] - DmkjConf.TimesRange[1]
			if math.random(v) <= (dmkjCount - DmkjConf.TimesRange[1] + 1) then
				consumeType = 3		-- 珍品
			end
		end
	end	
	
	local tbIdx = GetDmkjRandTableIndex()		-- 寻宝物品列表索引
	randItemList = DmkjConf.RandItemList[tbIdx][consumeType]

	local nRandom = System.getRandomNumber(10000) + 1	--随机数值：1 - 10000
	for _, v in ipairs(randItemList) do
		if nRandom >= v.rand[1] and nRandom <= v.rand[2] then
			local rd = math.random(10000)
			for _, k in ipairs(v.list) do
				if rd >= k.rand[1] and rd <= k.rand[2] then
					id = k.id
					bind = k.bind or 1
					num = k.count or 1
					initSmithId = k.initSmithId or 0
					break	
				end
			end

			--print(string.format("tb:type:random:rd:prom; [%d:%d:%d:%d:%d]", tbIdx, consumeType, nRandom, rd, v.prompt))
			Prompt = v.prompt
			break
		end
	end

	if initSmithId > 0 then 				--需要生产极品属性
		local job 		= 0 				--无角色职业要求
		local equipType = Item.getItemPropertyById( id, Item.ipItemType )  	--有装备类型要求
		initSmithAttr = Item.generateOneSmithAttr( sysarg, initSmithId, job, equipType )
		
		--local attrType, attrSign, attrValue = Item.parseAttrFromValue( initSmithAttr, 0, 0, 0 )
		--print( "StartXB, equipType="..equipType..", initSmithId="..initSmithId..", initSmithAttr="..initSmithAttr..", type="..attrType..", sign="..attrSign..", value="..attrValue )
	end

	Dmkj.addItem(sysarg, id, num, 0, 0, bind, initSmithAttr)
	Dmkj.addLog(sysarg, 0, 0, id, Prompt, equipStar, initSmithAttr)
	if Prompt > 0 then
		local strItemLink = Item.getItemLinkMsg(id)
		local str = string.format(Lang.ScriptTips.zf685, Actor.getName(sysarg), strItemLink)
		System.broadcastTipmsg(str, ttScreenCenter + ttChatWindow)		
	end

	-- 如果是从次数物品列表中抽得，则重置
	if consumeType == 3 then
		var.dmkjCount = nil
	else	
		var.dmkjCount = dmkjCount + 1
	end

	-- 每日寻宝次数
	if var.days.dmkjTimes == nil then
		var.days.dmkjTimes = 1
	else
		var.days.dmkjTimes = var.days.dmkjTimes + 1
	end

	return id, num, bind, initSmithAttr
end

--个人寻宝库请求
DmkjOpFuncList[DmkjOpId.enInfo] = function (sysarg,args)
	local var = Actor.getStaticVar(sysarg)
	local dmkjPerCount = var.dmkjPerCount or 0
	if dmkjPerCount < DmkjConf.DayMaxCount then
		local nTime = System.getCurrMiniTime()
		
		if not var.dmkjFreshTime then	
			RefreshStore(sysarg, nTime, 0)
		elseif var.dmkjFreshTime <= nTime then
			RefreshStore(sysarg, nTime, nTime - var.dmkjFreshTime)
		end
	end

	SendPersonalDmkjInfo(sysarg)
end

--个人寻宝库刷新
DmkjOpFuncList[DmkjOpId.enRefresh] = function (sysarg,args)
	if true then
		return
	end

	-- cost
	local var = Actor.getStaticVar(sysarg)
	local dmkjPerCount = var.dmkjPerCount or 0
	if dmkjPerCount >= DmkjConf.DayMaxCount then
		return
	end

	local dmkjFreshCount = var.dmkjFreshCount or 0
	local curFresh = dmkjFreshCount + 1
	
	local DmParam = DmkjConf.DmParam[3][1]
	if not DmParam then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.dm00001, ttFlyTip)
		return
	end

	local Gold = DmParam.yb * curFresh
	if Actor.getMoneyCount(sysarg, mtYuanbao) < Gold then
		Actor.sendItemLack(sysarg, qatYuanbao, 0, Gold)
		return
	end

	local bResult = Actor.changeMoney(sysarg, mtYuanbao, -Gold, GameLog.clDmkjConsumeMoney, Lang.LogTips.dm0003)
	if bResult == false then
		return
	end

	var.dmkjFreshCount = curFresh
	local nTime = System.getCurrMiniTime()
	RefreshStore(sysarg, nTime, 0)

	SendPersonalDmkjInfo(sysarg)
end

--个人寻宝库下发
function SendPersonalDmkjInfo(sysarg)
	local var = Actor.getStaticVar(sysarg)
	local npack = DataPack.allocPacket(sysarg, 36, 1)
	if not npack then return end
	DataPack.writeByte(npack, var.dmkjPerCount or 0)
	DataPack.writeUInt(npack, var.dmkjFreshCount or 0)
	DataPack.writeUInt(npack, var.dmkjFreshTime or 0)
	local dmkjLibId = var.dmkjLibId or 1
	local libNum = #DmkjConf.RefreshList[dmkjLibId]
	DataPack.writeByte(npack, libNum)
	for i = 1, libNum do
		local libIndex = var.DmkjRefreshLib[i] or 1
		local dmkjLib = DmkjConf.RefreshList[dmkjLibId]
		local dmkjLibItem = dmkjLib[i][libIndex]
		DataPack.writeWord(npack, dmkjLibItem.id)		--物品id
		DataPack.writeInt(npack, dmkjLibItem.count)		--数量
		DataPack.writeByte(npack, dmkjLibItem.bind or 1)--绑定
		DataPack.writeByte(npack, var.DmkjSelect[i] or 0)
	end

	DataPack.flush(npack)
end

function SendPersonalDmkjAward(sysarg, nCount, nIndex)
	local npack = DataPack.allocPacket(sysarg, 36, 5)
	if not npack then return end
	DataPack.writeByte(npack, nCount)
	DataPack.writeByte(npack, nIndex)

	DataPack.flush(npack)
end

function RefreshStoreCrossDay(sysarg)
	local var = Actor.getStaticVar(sysarg)
	var.dmkjPerCount = 0
	var.dmkjFreshCount = 0
	var.dmkjFreshTime = 0
	var.dmkjLibId = nil
	var.DmkjRefreshLib = {}
	var.DmkjSelect = {}

	local nTime = System.getCurrMiniTime()
	RefreshStore(sysarg, nTime, 0)
end

--个人寻宝库选择
function GetDmkjLibIndex()
	--local nCombineDays = System.getDaysSinceCombineServer() -- 合服天数
	local nOpenDays = System.getDaysSinceOpenServer() --开区天数
	if nOpenDays <= 9 then
		return 1
	elseif nOpenDays <= 19 then
		return 2
	elseif nOpenDays <= 29 then
		return 3
	elseif nOpenDays <= 59 then
		return 4
	elseif nOpenDays <= 89 then
		return 5
	elseif nOpenDays <= 119 then
		return 6
	elseif nOpenDays <= 149 then
		return 7
	else 
		return 8
	end
end

--刷新寻宝库
function RefreshStore(sysarg, time, interval)
	local var = Actor.getStaticVar(sysarg)
	if not var.DmkjRefreshLib then
		var.DmkjRefreshLib = {}
	end
	if not var.DmkjSelect then
		var.DmkjSelect = {}
	end

	local dmkjLibId = var.dmkjLibId or GetDmkjLibIndex()
	local dmkjLib = DmkjConf.RefreshList[dmkjLibId]
	for i = 1, #dmkjLib do
		if not var.DmkjSelect[i] then
			var.DmkjRefreshLib[i] = 1
			if var.dmkjLibId then
				local rd = math.random(10000)
				for k, v in ipairs(dmkjLib[i]) do
					if rd >= v.rand[1] and rd <= v.rand[2] then
						var.DmkjRefreshLib[i] = k
						break
					end
				end
			end
		end
	end

	var.dmkjLibId = dmkjLibId
	if interval > 0 then 
		var.dmkjFreshTime = time + DmkjConf.RefreshInterval - (interval % DmkjConf.RefreshInterval)
	else
		var.dmkjFreshTime = time + DmkjConf.RefreshInterval
	end
end

--个人寻宝库领奖
DmkjOpFuncList[DmkjOpId.enAward] = function (sysarg,args)
	if true then
		return
	end

	local AwardType = args[2]
	local var = Actor.getStaticVar(sysarg)
	local dmkjPerCount = var.dmkjPerCount or 0
	if dmkjPerCount >= DmkjConf.DayMaxCount then
		return
	end

	local AwardNum = 1
	if AwardType == 0 then
		AwardNum = DmkjConf.DayMaxCount - dmkjPerCount
	end
	
	-- cost
	local DmParam = DmkjConf.DmParam[2][1]
	if not DmParam then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.dm00001, ttFlyTip)
		return
	end

	if Dmkj.getStoreRestCount(sysarg) < AwardNum then
		Actor.sendTipmsg(sysarg,string.format(Lang.ScriptTips.dm00002, AwardNum), ttFlyTip)
		return
	end

	local Gold = DmParam.yb * AwardNum
	local tItem = DmParam.item

	if Actor.getItemCount(sysarg, tItem.id) >= tItem.count * AwardNum then
		if Actor.removeItem(sysarg, tItem.id, tItem.count * AwardNum) ~= tItem.count * AwardNum then
			return
		end
	else
		if Actor.getMoneyCount(sysarg, mtYuanbao) < Gold then
			Actor.sendItemLack(sysarg, qatYuanbao, 0, Gold)
			return
		end
		
		local bResult = Actor.changeMoney(sysarg, mtYuanbao, -Gold, GameLog.clDmkjConsumeMoney, Lang.LogTips.dm0002)
		if bResult == false then
			return
		end
	end

	if AwardNum == 1 then
		local randTable = {}
		for i = 1, 10 do
			if not var.DmkjSelect[i] then
				table.insert(randTable, i)
			end
		end

		local nSeed = #randTable
		if nSeed <= 0 then
			return
		end

		local nRandom = math.random(nSeed)
		local nIndex = randTable[nRandom]

		-- awards
		local dmkjLibId = var.dmkjLibId
		local nAardIndex = var.DmkjRefreshLib[nIndex]	
		local dmkjLib = DmkjConf.RefreshList[dmkjLibId]
		local award = dmkjLib[nIndex][nAardIndex] or dmkjLib[nIndex][1]
		Dmkj.addItem(sysarg, award.id, award.count, 0, 0, award.bind)

		local Prompt = award.prompt or 0
		Dmkj.addLog(sysarg, 0, 0, award.id, Prompt)
		if Prompt > 0 then
			local strItemLink = Item.getItemLinkMsg(award.id)
			local str = string.format(Lang.ScriptTips.zf686, Actor.getName(sysarg), strItemLink)
			System.broadcastTipmsg(str, ttScreenCenter + ttChatWindow)		
		end
		
		var.DmkjSelect[nIndex] = 1
		var.dmkjPerCount = dmkjPerCount + 1
		SendPersonalDmkjAward(sysarg, dmkjPerCount + 1, nIndex)
	else
		local dmkjLibId = var.dmkjLibId
		local dmkjLib = DmkjConf.RefreshList[dmkjLibId]
		for i = 1, #dmkjLib do
			if not var.DmkjSelect[i] then
				local nAardIndex = var.DmkjRefreshLib[i]	
				local award = dmkjLib[i][nAardIndex] or dmkjLib[i][1]
				Dmkj.addItem(sysarg, award.id, award.count, 0, 0, award.bind)

				local Prompt = award.prompt or 0
				Dmkj.addLog(sysarg, 0, 0, award.id, Prompt)
				if Prompt > 0 then
					local strItemLink = Item.getItemLinkMsg(award.id)
					local str = string.format(Lang.ScriptTips.zf686, Actor.getName(sysarg), strItemLink)
					System.broadcastTipmsg(str, ttScreenCenter + ttChatWindow)		
				end

				var.DmkjSelect[i] = 1
			end
		end

		var.dmkjPerCount = DmkjConf.DayMaxCount
		SendPersonalDmkjAward(sysarg, DmkjConf.DayMaxCount, 0)
	end

	--成就事件
	Actor.triggerAchieveEvent(sysarg, 45, 2, AwardNum)
end

--寻宝
DmkjOpFuncList[DmkjOpId.enDm] = function (sysarg,args)
	local TreasureType = args[2]	--类型1,2,3 = 1,5,10
	--local UseYB = args[3]

	local DmParam = DmkjConf.DmParam[1][TreasureType]
	if not DmParam then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.dm00001, ttFlyTip)
		return
	end
	
	local TreasureTime = DmParam.count
	local Gold = DmParam.yb

	if Dmkj.getStoreRestCount(sysarg) < TreasureTime then
		Actor.sendTipmsg(sysarg,string.format(Lang.ScriptTips.dm00002, TreasureTime), ttFlyTip)
		return
	end

	local tItem = DmParam.item
	if not tItem then
		return 
	end
	
	local consumeType = 2
	local useGold = true
	local var = Actor.getStaticVar(sysarg)
	if TreasureType == 1 and Actor.getItemCount(sysarg, tItem.id) >= tItem.count then
		if Actor.removeItem(sysarg, tItem.id, tItem.count) ~= tItem.count then
			return
		end
		consumeType = 1
		useGold = false
	else
		if Actor.getItemCount(sysarg, tItem.id) >= tItem.count then
			if Actor.removeItem(sysarg, tItem.id, tItem.count) == tItem.count then
				useGold = false
			end
		end
		if useGold then
			if Actor.getMoneyCount(sysarg, mtYuanbao) < Gold then
				Actor.sendItemLack(sysarg, qatYuanbao, 0, Gold)
				return
			end
			
			local bResult = Actor.changeMoney(sysarg, mtYuanbao, -Gold, GameLog.clDmkjConsumeMoney, Lang.LogTips.dm0001)
			if bResult == false then
				return
			end
		end
		local dmkjYb = var.dmkjYb or 0
		dmkjYb = dmkjYb + Gold
		var.dmkjYb = dmkjYb
	end
	
	local TreasureHuntValue = var.TreasureHuntValue or 0
	TreasureHuntValue = TreasureHuntValue + TreasureTime
	var.TreasureHuntValue = TreasureHuntValue	--宝藏积分增加
	
	NationwideRedPacketsDmkjHandle(sysarg, TreasureTime)
	operationDmkjHandler(sysarg, TreasureTime, useGold) 			--运营活动寻宝次数

	local itemList = {}
	for i = 1, TreasureTime do
		local id, num, bind, initSmithAttr = StartXB(sysarg, consumeType)	--开始寻宝
		table.insert(itemList, {id = id, num = num, bind = bind, initSmithAttr = initSmithAttr})	
	end

	local npack = DataPack.allocPacket(sysarg, 36, 2)
	if not npack then return end
	DataPack.writeInt(npack, TreasureHuntValue)		-- 宝藏积分
	DataPack.writeWord(npack, TreasureTime)				-- 物品总数量			
	DataPack.writeWord(npack, #itemList)				-- 记录数量
	for k, v in ipairs(itemList) do
		DataPack.writeByte(npack, 0)					--type
		DataPack.writeInt(npack, v.num)					--数量
		DataPack.writeWord(npack, v.id)					--物品id
		DataPack.writeByte(npack, 0)					--品质
		DataPack.writeByte(npack, 0)					--强化
		DataPack.writeByte(npack, v.bind)				--绑定
		DataPack.writeInt(npack, v.initSmithAttr)			--极品属性
	end
	DataPack.flush(npack)

	--成就事件
	Actor.triggerAchieveEvent(sysarg, 45, 5, TreasureTime)
end

--下发首页数据
DmkjOpFuncList[DmkjOpId.enIndex] = function (sysarg,args)

	local var = Actor.getStaticVar(sysarg)
	if not var.TreasureHuntValue then 
	   var.TreasureHuntValue = 0 
	end
	local TreasureHuntValue = var.TreasureHuntValue
	
	--下发配置信息
	local npack = DataPack.allocPacket(sysarg, 36, 8)	--
	if npack == nil then return end

	local data = DmkjConf.DmParam[1]
	local count = #data
	
	DataPack.writeUInt(npack, TreasureHuntValue)		--宝藏积分增加
	DataPack.writeByte(npack, count)
	for i = 1, count do
		DataPack.writeInt(npack, data[i].yb)
	end
	DataPack.flush(npack)
	
	--下发日志
	Dmkj.sendAllLog(sysarg, 2)
end


--宝藏积分兑换物品
DmkjOpFuncList[DmkjOpId.enExChangeItem] = function (sysarg,args)
	local nType = args[2]				-- 类型索引, 对应该TreasureIntegralCfg.lua -- type字段
	local nId = args[3]					-- 索引ID, 查看TreasureIntegralCfg.lua -- ExChangeData表的id
	
	if not TreasureIntegral then
		return false
	end
	
	local config
	for key ,value in ipairs(TreasureIntegral) do
		if value.type == nType then
			for id, data in ipairs(value.ExChangeData) do
				if data.id == nId then
					config = data
					break
				end
			end
		end
	end
	if not config then
		return false
	end

	if config.openDay and config.openDay > 0 then
		local days = System.getDaysSinceOpenServer()
		if days < config.openDay then
			return false
		end
	end

	local var = Actor.getStaticVar(sysarg)
	if not var.TreasureHuntValue then 
	   var.TreasureHuntValue = 0 
	end
	local nTreasureHuntValue = var.TreasureHuntValue
	
	if nTreasureHuntValue < config.needScore then
		Actor.sendTipmsg(sysarg, Lang.ScriptTips.zf131, ttFlyTip)
		return false
	end
	
	if Awards.CheckBagGridCount(sysarg,config.award) == false then
		return false
	end

	--检查消耗
	if nType ~= 6 then
		local consume = config.consume
		if not CheckConsumeCond(sysarg, consume) then
			return false 
		end
	end

	--扣除消耗
	local nStrong = 0
	local nInject = 0
	local nLucky = 0
	
	for _,item in ipairs(config.consume) do
		if item then
			if item.type == 0 then
				local nItem = Item.getBagItemPtrById(sysarg,item.id)
				if nItem then
					local itemType = Item.getItemProperty(sysarg, nItem, Item.ipItemType, 0)
					if itemType > Item.itUndefinedType and itemType < Item.itEquipMax  then
						local nTempStrong = Item.getItemProperty(sysarg, nItem, Item.ipItemStrong, 0)
						local nTempInject = Item.getItemProperty(sysarg, nItem, Item.ipItemInjectLevel, 0)
						local nTempLucky = Item.getItemProperty(sysarg, nItem, Item.ipItemLuck, 0)
						if nTempStrong > nStrong then
							nStrong = nTempStrong
						end
						if nTempInject > nInject then
							nInject = nTempInject
						end
						if nTempLucky > nLucky then
							nLucky = nTempLucky
						end
					end
					if Actor.removeItemByPtr(sysarg, nItem, item.count, true, "ChangeConsume", 997) ~= item.count then
						return
					end
				end
			end
		end	
	end
	
	var.TreasureHuntValue = nTreasureHuntValue - config.needScore
	
	local award = config.award[1]
	local nNewItem = Item.createItem(award.id,award.count,nStrong,0,award.bind)
	Item.addItem(sysarg, nNewItem, "enExChangeItem", 997)
	if nType ~= 6 then
		if nLucky > 0 then
			Item.setItemProperty(sysarg, nNewItem, Item.ipItemLuck, nLucky)
		end
		if nInject > 0 then
			Item.setItemProperty(sysarg, nNewItem, Item.ipItemInjectLevel, nInject)
		end
	end
	
	Actor.sendTipmsg(sysarg, string.format(Lang.ScriptTips.zf168,Item.getItemName(config.award[1].id)), ttFlyTip)
	
	local netPack = DataPack.allocPacket(sysarg, 36, 10)
	if netPack ~= nil then 
		DataPack.writeInt(netPack, var.TreasureHuntValue)
		DataPack.flush(netPack)
	end
	
	--添加全服公告
	local strItemLink = Item.getItemLinkMsg(config.award[1].id)
	local str = string.format(Lang.ScriptTips.zf676, Actor.getName(sysarg), strItemLink)
	Dmkj.addIntegralNotice(sysarg, str)
end

EventCallDispatcher.registerEventCall(BaseTypes.ActorEventId.aeDmkj, EventCallDispatcher.HandlerDmkjOp)


